﻿using System;
using System.Collections.Concurrent;
using Inovout.Descriptors;
using System.Collections.Generic;
using NHibernate;
using NHibernate.Mapping;
using NHibernate.Criterion;

namespace Inovout.Models
{
    public class PersistentProperty
    {
        private string propertyName;
        private Type ownerType;

        public string PropertyName
        {
            get { return propertyName; }
        }

        public Type PropertyType
        {
            get { return fieldPropertyDescriptor.PropertyType; }
        }
        public Type OwnerType
        {
            get { return ownerType; }
        }

        public PersistentProperty(string propertyName, Type ownerType)
        {
            ArgumentAssert.IsNotDefault(propertyName, "propertyName");
            ArgumentAssert.IsNotNull(ownerType, "ownerType");
            this.propertyName = propertyName;
            this.ownerType = ownerType;
            persistentPropertyDescriptor = TypeDescriptor.Create(ownerType);
            fieldPropertyDescriptor = persistentPropertyDescriptor.GetProperty(propertyName);
            //NHibernate.Cfg.Configuration nhibernateConfiguration = ComponentManager.Resolve<NHibernate.Cfg.Configuration>();
            //PersistentClass persistentClass = nhibernateConfiguration.GetClassMapping(ownerType);
            //Property property = persistentClass.GetProperty(propertyName);
        }

        private TypeDescriptor persistentPropertyDescriptor;
        private PropertyDescriptor fieldPropertyDescriptor;
        private static IDictionary<NameObjectKey, PersistentProperty> persistentPropertyDictionary = new ConcurrentDictionary<NameObjectKey, PersistentProperty>();
        public static PersistentProperty Register(string propertyName, Type ownerType)
        {
            ArgumentAssert.IsNotDefault(propertyName, "propertyName");
            ArgumentAssert.IsNotNull(ownerType, "ownerType");

            NameObjectKey persistentPropertyKey = new NameObjectKey(propertyName, ownerType);
            PersistentProperty persistentProperty;
            if (persistentPropertyDictionary.TryGetValue(persistentPropertyKey, out persistentProperty))
            {
                persistentProperty = new PersistentProperty(propertyName, ownerType);
                persistentPropertyDictionary.Add(persistentPropertyKey, persistentProperty);
            }
            else
            {
                persistentProperty = new PersistentProperty(propertyName,ownerType);
            }
            return persistentProperty;
        }
        public ICriterion Eq(object value)
        {
            return Expression.Eq(PropertyName, value);
        }
    }
}
